#include "ttftestwidget.h"

TTFTestModel::TTFTestModel():BHXJGLModel()
{

}
void TTFTestModel::Init(BHXJGLFUN *glcore,BHXJGLTTF* ttf)
{
    this->gl=glcore;
    this->ttf=ttf;
    BHXJGLTTFMesh *m=new BHXJGLTTFMesh();
    glm::mat4 mat4=glm::mat4(1.0);
    mat4=glm::scale(mat4,glm::vec3(1,1,0.08));

    mat4=glm::translate(mat4,glm::vec3(-1.5,0,0));
    ttf->addTextToMesh(m,QString("冰").begin()->unicode(),mat4);

    mat4=glm::translate(mat4,glm::vec3(1,0,0));
    ttf->addTextToMesh(m,QString("河").begin()->unicode(),mat4);

    mat4=glm::translate(mat4,glm::vec3(1,0,0));
    ttf->addTextToMesh(m,QString("洗").begin()->unicode(),mat4);

    mat4=glm::translate(mat4,glm::vec3(1,0,0));
    ttf->addTextToMesh(m,QString("剑").begin()->unicode(),mat4);


    //加入网格并初始化
    this->meshes.push_back(m);
    m->Init(this->gl);
}










TTFTestWidget::TTFTestWidget(QWidget *parent) : QOpenGLWidget(parent)
{
    QSurfaceFormat surfaceFormat(this->format());
    //surfaceFormat.setDepthBufferSize(0);   //不使用深度缓存
    //surfaceFormat.setStencilBufferSize(0); //
    surfaceFormat.setSamples(8);
    setFormat(surfaceFormat);

    setFocusPolicy(Qt::StrongFocus); startTimer(1000/60);

}
TTFTestWidget::~TTFTestWidget()
{
    this->keys.clear();
    delete(ttf);
}


void TTFTestWidget::initializeGL()
{
    initializeOpenGLFunctions();

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    shader.Init(this,":/vertexttf.vert",":/fragmentttf.frag");
    shadernormal.Init(this,":/vertexttf1.vert",":/fragmentttf1.frag",":/ttfgeotry.geom");
    ttf=new  BHXJGLTTF();
    //ttf->Init(this,&shader, "./font/DejaVuSansMono/DejaVuSansMono-1.ttf");
    ttf->Init(this, "./font/FZKTFW.TTF");
    ttfmodl.Init(this,ttf);

    camera.SetPosition(glm::vec3(0.0f, 0.0f, 3.0f));
    //camera.SetYaw(180);
    camera.PitchLimit();


    projection    = glm::mat4(1.0f);
    float width=static_cast<float>(this->width());
    float height=static_cast<float>(this->height());
    height=height>0?height:1;
    projection = glm::perspective(glm::radians(45.0f), width / height, 0.1f, 100.0f);
    //projection = glm::ortho(-width / height, width / height,-1.f, 1.f, 0.1f, 100.0f);

    model = glm::mat4(1.0f);
    model[0]=glm::vec4(1,0,0,0);
    model[1]=glm::vec4(0,1,0,0);
    model[2]=glm::vec4(0,0,1,0);
    model[3]=glm::vec4(0,0,0,1);


    projectionID= this->shader.getUniformLocation("projection");
    viewID= this->shader.getUniformLocation("view");
    modelID= this->shader.getUniformLocation("model");

}

void TTFTestWidget::paintGL()
{
    using namespace glm;

    glEnable(GL_STENCIL_TEST);
    glEnable(GL_DEPTH_TEST);

    glStencilMask(0xFF);//重新开启写进模板缓冲 先 启用重写，在清理模板缓存才有效
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

    //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    //    glEnable(GL_CULL_FACE);
    //    glCullFace(GL_FRONT);
    //    glFrontFace(GL_CW);

    if(_PaintLine)
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    else
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);



    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    glStencilFunc(GL_ALWAYS, 1, 0xFF); // 所有的片段都应该更新模板缓冲
    glStencilMask(0xFF); // 启用模板缓冲写入
    this->shader.use();
    this->shader.setVec3("Color",vec3(0,0.3,0));
    BHXJGLPaintParam p;

    p.setView(camera.View(true));
    p.setProjection(projection);
    p.setPosition(glm::vec3(0.0,0.0,1),true);

    //ttf->PaintString("冰河洗剑",p,&shader);

    {
        shader.use();
        //glm::vec3 parallellightdir= glm::vec3( p.Model() *glm::vec4(0,0,-1,0));
        //glm::vec3 parallellightdir= p.Position()-camera.GetPosition();
        glm::vec3 parallellightdir= -camera.CBase(true)[2];
        shader.setVec3("parallellight.direction",parallellightdir);
        shader.setVec3("parallellight.ambient",glm::vec3(0.3f));
        shader.setVec3("parallellight.diffuse",glm::vec3(0.35f));
        shader.setVec3("parallellight.specular",glm::vec3(0.35f));
        shader.setVec3("viewPos",camera.GetPosition());



        shader.setMat4("projection",p.Projection());
        shader.setMat4("view",p.View());
        shader.setMat4("model",p.Model());
        shader.setVec3("material.ambient",glm::vec3(0,1,0));
        shader.setVec3("material.diffuse",glm::vec3(0,1,0));
        shader.setVec3("material.specular",glm::vec3(0,1,0));
        shader.setVec3("material.emission",glm::vec3(0,0,0));
        shader.setFloat("material.shininess",32.f);

        ttfmodl.Paint(p,&shader);


        this->shadernormal.use();
        this->shadernormal.setVec3("Color",vec3(1,1,1));
        ttfmodl.Paint(p,&shadernormal);

    }





    //glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
    glStencilFunc(GL_EQUAL, 0, 0xFF);
    glStencilMask(0x00); // 禁止模板缓冲的写入
    glDisable(GL_DEPTH_TEST);
    this->shader.use();
    shader.setVec3("material.ambient",glm::vec3(1,0,0));
    shader.setVec3("material.diffuse",glm::vec3(1,0,0));
    shader.setVec3("material.specular",glm::vec3(1,0,0));
    shader.setVec3("material.emission",glm::vec3(1,0,0));
    p.setPosition(glm::vec3(0.00,0.00,0.5),true);

    ttf->PaintString("冰河洗剑",p,&shader);



    //    glStencilMask(0xFF);//重新开启写进模板缓冲
    //    glStencilFunc(GL_ALWAYS, 1, 0xFF); //因为glClear()函数并不能清除掉模板缓冲，所以我们需要还原缓冲模板缓冲功能函数glStencilFunc
    //    glEnable(GL_DEPTH_TEST);

}

void TTFTestWidget::resizeGL(int width, int height)
{
    projection    = glm::mat4(1.0f);
    height=height>0?height:1;
    projection = glm::perspective(glm::radians(45.0f), static_cast<float>(width) / static_cast<float>(height), 0.1f, 100.0f);
    // projection = glm::ortho(-(float)width / (float)height, (float)width / (float)height,-1.f, 1.f, 0.1f, 100.0f);
}



void TTFTestWidget::mousePressEvent(QMouseEvent *e)
{
    if(e->button()==Qt::LeftButton)
    {
        setCursor(QCursor(Qt::BlankCursor));
        //this->setMouseTracking(true);
        p=e->globalPos();
        std::cout << "pressin" << std::endl;
    }
    //  if(e->button()==Qt::RightButton)
    //  {
    //    setCursor(QCursor(Qt::ArrowCursor));
    //    this->setMouseTracking(false);
    //  }

}
void TTFTestWidget::mouseReleaseEvent(QMouseEvent *e)
{
    if(e->button()==Qt::LeftButton)
    {
        setCursor(QCursor(Qt::ArrowCursor));
        //this->setMouseTracking(true);
        //p=e->globalPos();
    }
}
void TTFTestWidget::mouseDoubleClickEvent(QMouseEvent *)
{

}
void TTFTestWidget::mouseMoveEvent(QMouseEvent *e)
{
    if(!move)
    {
        std::cout << "动了但忽略" << std::endl;
        return;
    }
    move=false;
    {
        int pitch=p.y()-e->globalY();
        int yaw=e->globalX()-p.x();
        if(pitch==0&&yaw==0)
        {}
        else
        {   QCursor::setPos(p);

            this->camera.SetPitch(camera.GetPitch()+pitch*0.15f);
            this->camera.SetYaw(camera.GetYaw()+yaw*0.15f);
            //this->update();
            updated=true;
        }
        //QCursor::setPos(p);
    }
    move=true;
}


void TTFTestWidget::keyPressEvent(QKeyEvent *e)
{
    keys[e->key()] = true; QWidget::keyPressEvent(e);
}
void TTFTestWidget::keyReleaseEvent(QKeyEvent *e)
{
    keys[e->key()] = false; QWidget::keyReleaseEvent(e);
}

void TTFTestWidget::timerEvent(QTimerEvent *)
{
    if(keys[Qt::Key_W])
    {
        this->camera.ForWard_Move(0.06f);
        updated=true;
    }
    if(keys[Qt::Key_S])
    {
        this->camera.BackWard_Move(0.06f);
        updated=true;
    }
    if(keys[Qt::Key_A])
    {
        this->camera.LeftWard_Move(0.06f);
        updated=true;
    }
    if(keys[Qt::Key_D])
    {
        this->camera.RightWard_Move(0.06f);
        updated=true;
    }
    if(updated)
    {
        this->update();

        updated=false;
    }
}

